package com.ruoyi.store.service.impl;

import com.ruoyi.basedata.api.RemoteGoodsService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.store.domain.StockTaking;
import com.ruoyi.store.domain.StockTakingDetail;
import com.ruoyi.store.mapper.*;
import com.ruoyi.store.service.IStockTakingService;
import com.ruoyi.system.api.domain.basedata.Goods;
import com.ruoyi.system.api.domain.store.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 库存盘点Service业务层处理
 *
 * @author lmj
 * @date 2024-11-04
 */
@Service
@Slf4j
@Transactional
public class StockTakingServiceImpl implements IStockTakingService {
    @Autowired
    private StockTakingMapper stockTakingMapper;
    @Autowired
    private StockTakingDetailMapper stockTakingDetailMapper;
    @Autowired
    private RemoteGoodsService remoteGoodsService;
    @Autowired
    private StockInMapper stockInMapper;
    @Autowired
    private StockInDetailMapper stockInDetailMapper;
    @Autowired
    private StockOutMapper stockOutMapper;
    @Autowired
    private StockOutDetailMapper stockOutDetailMapper;
    @Autowired
    private WarehouseGoodsMapper warehouseGoodsMapper;

    /**
     * 查询库存盘点
     *
     * @param id 库存盘点主键
     * @return 库存盘点
     */
    @Override
    public StockTaking selectStockTakingById(Integer id) {
        return stockTakingMapper.selectStockTakingById(id);
    }

    /**
     * 查询库存盘点列表
     *
     * @param stockTaking 库存盘点
     * @return 库存盘点
     */
    @Override
    public List<StockTaking> selectStockTakingList(StockTaking stockTaking) {
        return stockTakingMapper.selectStockTakingList(stockTaking);
    }

    /**
     * 新增库存盘点
     *
     * @param stockTaking 库存盘点
     * @return 结果
     */
    @Override
    public AjaxResult insertStockTaking(StockTaking stockTaking) {
        log.info("StockTakingServiceImpl insertStockTaking params:{}", stockTaking);
        //判断盘点单编号是否重复
        StockTaking stockTaking1 = stockTakingMapper.getStockTakingByCode(stockTaking.getTakingCode());
        if (stockTaking1 != null) {
            return AjaxResult.warn("盘点单编号重复，请修改！");
        }
        boolean flag = stockTakingMapper.insertStockTaking(stockTaking) > 0;
        if (!flag) {
            log.error("insertStockTaking fail");
            throw new RuntimeException("插入盘点单失败！");
        }
        StockTaking stockTaking2 = stockTakingMapper.getStockTakingByCode(stockTaking.getTakingCode());
        List<StockTakingDetail> stockTakingDetails = stockTaking.getStockTakingDetails();
        Integer takingId = stockTaking2.getId();
        for (StockTakingDetail stockTakingDetail : stockTakingDetails) {
            stockTakingDetail.setTakingId(takingId);
            boolean flag1 = stockTakingDetailMapper.insertStockTakingDetail(stockTakingDetail) > 0;
            if (!flag1) {
                log.error("insertStockTakingDetail fail");
                throw new RuntimeException("插入盘点单详情错误");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改库存盘点
     *
     * @param stockTaking 库存盘点
     * @return 结果
     */
    @Override
    public AjaxResult updateStockTaking(StockTaking stockTaking) {
        log.info("StockTakingServiceImpl updateStockTaking params:{}", stockTaking);
        boolean flag = stockTakingMapper.updateStockTaking(stockTaking) > 0;
        if (!flag) {
            log.error("updateStockTaking fail");
            throw new RuntimeException("更新盘点单错误");
        }
        List<StockTakingDetail> stockTakingDetails = stockTaking.getStockTakingDetails();
        for (StockTakingDetail stockTakingDetail : stockTakingDetails) {
            flag = stockTakingDetailMapper.updateStockTakingDetail(stockTakingDetail) > 0;
            if (!flag) {
                log.error("updateStockTakingDetail fail");
                throw new RuntimeException("更新盘点单详情错误");
            }
            //根据仓库id和商品id查询库存，然后修改库存数量
            WarehouseGoods warehouseGoods = new WarehouseGoods();
            warehouseGoods.setGoodsId(stockTakingDetail.getGoodsId());
            warehouseGoods.setHouseId(stockTaking.getHouseId());
            warehouseGoods.setStock(stockTakingDetail.getRealNum());
            flag = warehouseGoodsMapper.updateWarehouseGoodsByTaking(warehouseGoods) > 0;
            if (!flag) {
                log.error("updateWarehouseGoodsByTaking fail");
                throw new RuntimeException("更新库存错误");
            }
        }
        //盘点单和详情修改完成后需要添加出库单和入库单
        StockIn stockIn = new StockIn();
        List<StockInDetail> stockInDetails = new ArrayList<>();
        StockOut stockOut = new StockOut();
        List<StockOutDetail> stockOutDetails = new ArrayList<>();
        for (StockTakingDetail stockTakingDetail : stockTakingDetails) {
            if (stockTakingDetail.getTakingLess() > 0) {
                StockOutDetail stockOutDetail = new StockOutDetail();
                stockOutDetail.setGoodsId(stockTakingDetail.getGoodsId());
                stockOutDetail.setNum(stockTakingDetail.getTakingLess());
                stockOutDetail.setStockOutNumber(stockTakingDetail.getTakingLess());
                stockOutDetail.setCreateBy(SecurityUtils.getUsername());
                stockOutDetail.setCreateDate(new Date());
                stockOutDetails.add(stockOutDetail);
            }
            if (stockTakingDetail.getTakingMore() > 0) {
                StockInDetail stockInDetail = new StockInDetail();
                stockInDetail.setGoodsId(stockTakingDetail.getGoodsId());
                stockInDetail.setNum(stockTakingDetail.getTakingMore());
                stockInDetail.setNoPassNum(0);
                stockInDetail.setTotalNum(stockTakingDetail.getTakingMore());
                stockInDetail.setPassRate(1.0);
                //根据id获取商品
                R<Goods> r = remoteGoodsService.getGoodsById(stockTakingDetail.getGoodsId());
                log.info("getGoodsById result:{}", r);
                Goods goods = r.getData();
                if (goods.getId() == null) {
                    log.error("updateStockTaking getGoodsById fail");
                    throw new RuntimeException("获取商品错误");
                }
                stockInDetail.setCost(goods.getPrice());
                BigDecimal price = goods.getPrice();
                Integer takingMore = stockTakingDetail.getTakingMore();
                BigDecimal costAll = price.multiply(BigDecimal.valueOf(takingMore));
                // 设置到 stockInDetail4
                stockInDetail.setPassCost(costAll);
                stockInDetail.setCostAll(costAll);
                stockInDetail.setHouseId(stockTaking.getHouseId());
                stockInDetail.setCreateBy(SecurityUtils.getUsername());
                stockInDetail.setCreateDate(new Date());
                stockInDetails.add(stockInDetail);
            }
        }
        if (stockInDetails.size() > 0) {
            stockIn.setStockInCode("RK" + System.currentTimeMillis());
            stockIn.setOrderCode(stockTaking.getTakingCode());
            stockIn.setInventoryType(8);
            BigDecimal cost = BigDecimal.valueOf(0);
            int totalNum = 0;
            for (StockInDetail stockInDetail : stockInDetails) {
                cost = cost.add(stockInDetail.getCostAll());
                totalNum += stockInDetail.getTotalNum();
            }
            stockIn.setCost(cost);
            stockIn.setStatus(1);
            stockIn.setCreateBy(SecurityUtils.getUsername());
            stockIn.setCreateDate(new Date());
            stockIn.setPassRate(1.0);
            stockIn.setPassNum(totalNum);
            stockIn.setTotalNum(totalNum);
            stockIn.setNoPassNum(0);
            stockIn.setPassCost(cost);
            //添加入库和详情
            flag = stockInMapper.insertStockIn(stockIn) > 0;
            if (!flag) {
                log.error("updateStockTaking insertStockIn fail");
                throw new RuntimeException("添加入库单错误");
            }
            StockIn stockIn1 = stockInMapper.getStockInByCode(stockIn.getStockInCode());
            for (StockInDetail stockInDetail : stockInDetails) {
                stockInDetail.setStockInId(stockIn1.getId());
                flag = stockInDetailMapper.insertStockInDetail(stockInDetail) > 0;
                if (!flag) {
                    log.error("updateStockTaking insertStockInDetail fail");
                    throw new RuntimeException("添加入库单详情错误");
                }
            }
        }
        if (stockOutDetails.size() > 0) {
            stockOut.setStockOutCode("CK" + System.currentTimeMillis());
            stockOut.setOrderCode(stockTaking.getTakingCode());
            stockOut.setInventoryTypeId(7);
            stockOut.setStockStatus(2);
            int totalNum = 0;
            for (StockOutDetail stockOutDetail : stockOutDetails) {
                totalNum += stockOutDetail.getNum();
            }
            stockOut.setStockNum(totalNum);
            stockOut.setStockNumber(totalNum);
            stockOut.setCreateBy(SecurityUtils.getUsername());
            stockOut.setCreateDate(new Date());
            //添加出库和详情
            flag = stockOutMapper.insertTakingOut(stockOut) > 0;
            if (!flag) {
                log.error("updateStockTaking insertTakingOut fail");
                throw new RuntimeException("添加出库单详情错误");
            }
            StockOut stockOut1 = stockOutMapper.getStockOutByCode(stockOut.getStockOutCode());
            for (StockOutDetail stockOutDetail : stockOutDetails) {
                stockOutDetail.setStockOutId(stockOut1.getId());
                flag = stockOutDetailMapper.addTakingOutDetail(stockOutDetail) > 0;
                if (!flag) {
                    log.error("updateStockTaking addTakingOutDetail fail");
                    throw new RuntimeException("添加出库单详情错误");
                }
            }
        }


        return AjaxResult.success();
    }

    /**
     * 批量删除库存盘点
     *
     * @param ids 需要删除的库存盘点主键
     * @return 结果
     */
    @Override
    public int deleteStockTakingByIds(Integer[] ids) {
        return stockTakingMapper.deleteStockTakingByIds(ids);
    }

    /**
     * 删除库存盘点信息
     *
     * @param id 库存盘点主键
     * @return 结果
     */
    @Override
    public int deleteStockTakingById(Integer id) {
        return stockTakingMapper.deleteStockTakingById(id);
    }
}
